package com.business.wechat.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.business.bean.system.UserBean;
import com.business.wechat.bean.WeixinConfigBean;
import com.business.wechat.bean.WeixinTempMessage;
import com.business.wechat.handler.AbstractHandler;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import net.sf.rose.jdbc.DBUtils;
import net.sf.rose.jdbc.PageBean;
import net.sf.rose.jdbc.dao.BeanDAO;
import net.sf.rose.jdbc.query.BeanSQL;
import net.sf.rose.jdbc.service.Service;
import net.sf.rose.util.BeanWrapper;
import net.sf.rose.util.DataUtils;
import net.sf.rose.util.DateFormat;

/**
 * 
 * @author fengjian
 *
 */
public class WeixinUtils {

	private static Map<String, WeixinService> map = new HashMap<>();

	public static Map<String, WeixinService> getAllWeixinBean() {
		return map;
	}

	public static void initial() {
		Service service = new Service();
		Map<String, Object> params = new HashMap<>();
		params.put("inUsed", 1);
		List<WeixinConfigBean> list = DBUtils.getBeanListByMap(service, WeixinConfigBean.class, params);
		service.close();
		if (list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				WeixinConfigBean wc = list.get(i);
				WeixinService bean = new WeixinService();
				bean.setWxConfigBean(wc);
				WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
				configStorage.setAppId(wc.getAppId());
				configStorage.setSecret(wc.getAppSecret());
				configStorage.setToken(wc.getToken());
				configStorage.setAesKey(wc.getAesKey());
				bean.setConfigStorage(configStorage);

				WxMpService wxMpService = new WxMpServiceImpl();
				wxMpService.setWxMpConfigStorage(configStorage);
				bean.setMpService(wxMpService);

				WxPayConfig payConfig = new WxPayConfig();
				payConfig.setAppId(wc.getAppId());
				payConfig.setMchId(wc.getMchId());
				payConfig.setMchKey(wc.getMchKey());
				payConfig.setSubAppId(wc.getSubAppId());
				payConfig.setSubMchId(wc.getSubMchId());
				payConfig.setKeyPath(wc.getKeyPath());
				bean.setPayConfig(payConfig);

				WxPayService payService = new WxPayServiceImpl();
				payService.setConfig(payConfig);
				bean.setPayService(payService);
				// 使用工程名称作为微信项目名称
				bean.setWeixinName(wc.getProjectName());

				// 路由
				WxMpMessageRouter router = new WxMpMessageRouter(wxMpService);
				bean.setRouter(router);
				// 记录所有事件的日志
				AbstractHandler handler = null;
				if (wc.getLogHandlerClassName() != null) {
					handler = (AbstractHandler) DataUtils.getInstance(wc.getLogHandlerClassName());
					handler.setWeixinService(bean);
					router.rule().handler(handler).next();
				}
				// 关注事件
				if (wc.getSubscribeHandlerClassName() != null) {
					handler = (AbstractHandler) DataUtils.getInstance(wc.getSubscribeHandlerClassName());
					handler.setWeixinService(bean);
					handler.setWeixinService(bean);
					router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE)
							.handler(handler).end();
				}
				// 取消关注事件
				if (wc.getUnSubscribeHandlerClassName() != null) {
					handler = (AbstractHandler) DataUtils.getInstance(wc.getUnSubscribeHandlerClassName());
					handler.setWeixinService(bean);
					handler.setWeixinService(bean);
					router.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE)
							.handler(handler).end();
				}
				// 默认,转发消息给客服人员
				if (wc.getMsgHandlerClassName() != null) {
					handler = (AbstractHandler) DataUtils.getInstance(wc.getMsgHandlerClassName());
					handler.setWeixinService(bean);
					router.rule().async(false).handler(handler).end();
				}
				map.put(wc.getProjectName(), bean);
			}
			System.out.println("微信项目配置参数初始化加载成功...");
		}
	}

	public static WeixinService getWeixinBean(String weixinName) {
		return map.get(weixinName);
	}

	/**
	 * 发送模板消息
	 * 
	 * @param weixinName  - 微信公众号名称
	 * @param tempateName - 模板名称
	 * @param bean        - 数据对象，必须包含openId或userID属性
	 * @return
	 */
	public static PageBean sendTempletMessage(Service service, String weixinName, String tempateName, Object bean) {
		PageBean page = new PageBean();
		BeanDAO dao = new BeanDAO(service);
		BeanSQL query = dao.getQuerySQL();
		WeixinTempMessage wt = new WeixinTempMessage();
		wt.setWeixinName(weixinName);
		wt.setTempateName(tempateName);
		query.setEntityClass(WeixinTempMessage.class);
		query.createSql(wt);
		wt = dao.get();
		if (wt == null) {
			page.setSuccess(false);
			page.setMessage("微信公众号" + weixinName + "没有找到模板消息" + tempateName + "的配置！");
			return page;
		}
		String openId = null;
		BeanWrapper bw = new BeanWrapper(bean);
		if (bw.has("openId")) {
			Object obj = bw.get("openId");
			if (obj == null) {
				page.setSuccess(false);
				page.setMessage("参数对象bean中属性openId不能为空！");
				return page;
			} else {
				openId = obj.toString();
			}
		} else {
			if (bw.has("userID")) {
				Object obj = bw.get("userID");
				if (obj == null) {
					page.setSuccess(false);
					page.setMessage("参数对象bean中属性userID不能为空！");
					return page;
				} else {
					query.setEntityClass(UserBean.class);
					query.setSQL("select openId from SYS_USER where userID=?");
					query.addParameter(obj);
					UserBean user = dao.get();
					if (user == null) {
						page.setSuccess(false);
						page.setMessage("参数对象bean中属性userID没有找到用户数据！");
						return page;
					}
					openId = user.getOpenId();
				}
			} else {
				page.setSuccess(false);
				page.setMessage("参数对象bean中没有包含openId或userID属性！");
				return page;
			}
		}
		String tempateId = wt.getTempateId();
		WeixinService ws = WeixinUtils.getWeixinBean(weixinName);
		WxMpService wMpService = ws.getMpService();
		WxMpTemplateMessage tm = WxMpTemplateMessage.builder().toUser(openId).templateId(tempateId).build();
		String key = null;
		key = wt.getAttribute1();
		if (key != null && bw.has(wt.getProperty1())) {
			addTemplateData(tm, key, bw.get(wt.getProperty1()));
		}
		key = wt.getAttribute2();
		if (key != null && bw.has(wt.getProperty2())) {
			addTemplateData(tm, key, bw.get(wt.getProperty2()));
		}
		key = wt.getAttribute3();
		if (key != null && bw.has(wt.getProperty3())) {
			addTemplateData(tm, key, bw.get(wt.getProperty3()));
		}
		key = wt.getAttribute4();
		if (key != null && bw.has(wt.getProperty4())) {
			addTemplateData(tm, key, bw.get(wt.getProperty4()));
		}
		key = wt.getAttribute5();
		if (key != null && bw.has(wt.getProperty5())) {
			addTemplateData(tm, key, bw.get(wt.getProperty5()));
		}
		key = wt.getAttribute6();
		if (key != null && bw.has(wt.getProperty6())) {
			addTemplateData(tm, key, bw.get(wt.getProperty6()));
		}
		key = wt.getAttribute7();
		if (key != null && bw.has(wt.getProperty7())) {
			addTemplateData(tm, key, bw.get(wt.getProperty7()));
		}
		key = wt.getAttribute8();
		if (key != null && bw.has(wt.getProperty8())) {
			addTemplateData(tm, key, bw.get(wt.getProperty8()));
		}
		try {
			wMpService.getTemplateMsgService().sendTemplateMsg(tm);
		} catch (WxErrorException e) {
			page.setSuccess(false);
			page.setMessage("模板消息发送失败！原因：" + e.getMessage());
		}
		return page;
	}

	/**
	 * 给微信模板消息添加参数值
	 * @param tm
	 * @param name
	 * @param val
	 */
	private static void addTemplateData(WxMpTemplateMessage tm, String name, Object val) {
		if (val instanceof Date) {
			val = DateFormat.format((Date) val, DateFormat.DATE_FORMAT_3);
		}
		tm.addData(new WxMpTemplateData(name, val.toString()));
	}

}
